package com.authine.cloudpivot.ext.controller;

import cn.hutool.core.util.StrUtil;
import com.authine.cloudpivot.engine.api.facade.OrganizationFacade;
import com.authine.cloudpivot.engine.api.model.organization.DepartmentModel;
import com.authine.cloudpivot.engine.api.model.organization.UserModel;
import com.authine.cloudpivot.web.api.controller.base.BaseController;
import com.authine.cloudpivot.web.api.view.ResponseResult;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.collections4.MapUtils;
import org.apache.commons.lang.StringUtils;
import org.hibernate.query.internal.NativeQueryImpl;
import org.hibernate.transform.Transformers;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @Author hxd
 * @Date 2022/3/20 11:31
 * @Description
 **/
@RestController
@Slf4j
@RequestMapping("/api/homePages")
public class HomePagesContoller extends BaseController {

    @PersistenceContext
    EntityManager entityManager;

    //@GetMapping("rollMessage")
    //public ResponseResult<List<Map<String,Object>>> rollMessage(){
    //
    //    UserModel currentUser = getOrganizationFacade().getUser(getUserId());
    //
    //    String tableName = getTbName("xxtsgl");
    //
    //    StringBuilder sqlWhere = new StringBuilder(" where zt = '已启动' and CURRENT_DATE <= DATE_FORMAT(hdjzrq,'%Y-%m-%d') and( JSON_CONTAINS(hhxr ->'$[*].id', '\"")
    //            .append(currentUser.getId()).append("\"') or  JSON_CONTAINS(hhxr ->'$[*].id', '\"").append(currentUser.getDepartmentId()).append("\"') )   order by createdTime desc");
    //
    //    StringBuilder sqlData = new StringBuilder("select id,xxtsmc, DATE_FORMAT(createdTime,'%Y-%m-%d') as dateStr,tssm from ").append(tableName);
    //    String sql = sqlData.append(sqlWhere).append(" LIMIT 10").toString();
    //
    //
    //
    //    List<Map<String,Object>> resultList = entityManager.createNativeQuery(sql).unwrap(NativeQueryImpl.class)
    //            .setResultTransformer(Transformers.ALIAS_TO_ENTITY_MAP).getResultList();
    //
    //    if (CollectionUtils.isNotEmpty(resultList) && resultList.size()>10) {
    //        resultList = resultList.subList(0,10);
    //    }
    //
    //    return getOkResponseResult(resultList,"成功");
    //}

    @GetMapping("rollMessage")
    public ResponseResult<List<Map<String, Object>>> rollMessage() {

        String userId = getUserId();
        String xxtsglTableName = getTbName("xxtsgl");
        OrganizationFacade organizationFacade = getOrganizationFacade();

        //第一种情况，用户直接存在于 hhxr 混合选人控件选择的人员中，可直接把用户id作为搜索条件
        //第二种情况，用户的部门存在于 hhxr 混合选人控件选择的部门中
        //①获取登录用户的所有部门id
        List<String> departmentIds = new ArrayList<>();
        List<DepartmentModel> departmentsByUserId = organizationFacade.getDepartmentsByUserId(userId);
        for (DepartmentModel departmentModel : departmentsByUserId) {
            getAllParentDepartmentIds(departmentModel.getId(), departmentIds);
        }
        log.info("登录用户的本级+上级部门id集合:{}", departmentIds);
        log.info("登录用户的本级+上级部门id集合元素个数:{}", departmentIds);
        //②将用户的id存入departmentIds，下面有用
        departmentIds.add(userId);
        String departmentIdsSql = "'";
        for (int i = 0; i < departmentIds.size(); i++) {
            if (i != departmentIds.size() - 1) {
                departmentIdsSql = departmentIdsSql + departmentIds.get(i) + "|";
            } else {
                departmentIdsSql = departmentIdsSql + departmentIds.get(i);
            }
        }
        departmentIdsSql = departmentIdsSql + "'";
        log.info("departmentIdsSql:{}", departmentIdsSql);
        String selectSql = "select * from " + xxtsglTableName + " where zt = '已启动' and CURRENT_DATE <= DATE_FORMAT(hdjzrq,'%Y-%m-%d') and hhxr regexp " + departmentIdsSql;
        log.info("selectSql:{}", selectSql);
        List<Map<String, Object>> selectSql2Result = entityManager.createNativeQuery(selectSql).unwrap(NativeQueryImpl.class).setResultTransformer(Transformers.ALIAS_TO_ENTITY_MAP).getResultList();
        return getOkResponseResult(selectSql2Result, "成功");
    }

    public List<String> getAllParentDepartmentIds(String deparementId, List<String> departmentIds) {
        if (!departmentIds.contains(deparementId)) {
            departmentIds.add(deparementId);
        }
        String selectSQL = "select * from h_org_department where id = '" + deparementId + "'";
        List<Map<String, Object>> departmentList = entityManager.createNativeQuery(selectSQL.toString()).unwrap(NativeQueryImpl.class).setResultTransformer(Transformers.ALIAS_TO_ENTITY_MAP).getResultList();
        if (departmentList.size() > 0) {
            String parentId = (String) departmentList.get(0).get("parentId");
            if (org.apache.commons.lang3.StringUtils.isNotBlank(parentId) && !departmentIds.contains(deparementId)) {
                departmentIds.add(parentId);
            }
            String selectSQLForP = "select * from h_org_department where id = '" + parentId + "'";
            List<Map<String, Object>> departmentPList = entityManager.createNativeQuery(selectSQLForP.toString()).unwrap(NativeQueryImpl.class).setResultTransformer(Transformers.ALIAS_TO_ENTITY_MAP).getResultList();
            if (departmentPList.size() > 0) {
                getAllParentDepartmentIds(parentId, departmentIds);
            }
        }
        return departmentIds;
    }


    @GetMapping("getNotify")
    public ResponseResult getNotify(String isRead, Integer page, Integer size, String releaseDateStr, String name) {


        String tableName = getTbName("ZCGL_TZTG_SUB");
        StringBuilder sql = new StringBuilder("SELECT {} from ").append(tableName).append(" a where  a.creater ='").append(getUserId()).append("' ");

        if (StringUtils.isNotEmpty(isRead)) {
            sql.append(" and  a.isRead ='").append(isRead).append("'");
        }
        if (StringUtils.isNotEmpty(releaseDateStr)) {
            sql.append(" and DATE_FORMAT(a.createdTime,'%Y-%m-%d')= '").append(releaseDateStr).append("'");
        }
        if (StringUtils.isNotEmpty(name)) {
            sql.append(" and  a.name like '%").append(name).append("%'");
        }


        String countSql = "count(*) as count";
        String dataSql = "a.id, a.name as tzbt,a.tzrt, DATE_FORMAT(a.createdTime,'%Y-%m-%d') dateStr,a.isRead";

        BigInteger singleResult = (BigInteger) entityManager.createNativeQuery(StrUtil.format(sql, countSql)).getSingleResult();
        List<Map<String, Object>> resultList = Collections.EMPTY_LIST;
        if (singleResult != null && singleResult.intValue() > 0) {
            resultList = entityManager.createNativeQuery(StrUtil.format(sql.append(getlimit(page, size)), dataSql)).unwrap(NativeQueryImpl.class)
                    .setResultTransformer(Transformers.ALIAS_TO_ENTITY_MAP).getResultList();

        }

        Map<Object, Object> map = new HashMap<>();

        map.put("data", resultList);
        map.put("total", singleResult);


        return getOkResponseResult(map, "成功");
    }

    static Map<String, String> tableNameMap = new HashMap<>();

    private String getTbName(String schemaCode) {
        String tableName = tableNameMap.get(schemaCode);

        if (tableName == null) {
            String name = getBizObjectFacade().getTableName(schemaCode);

            if (name == null) {
                throw new RuntimeException("获取表名为空,schemaCode=".concat(schemaCode));
            }
            tableNameMap.put(schemaCode, name);
            return name;
        }
        return tableName;
    }

    String countSql = "count(*) as count";

    @GetMapping("getTodoList")
    public ResponseResult getTodoList(Integer page, Integer size, String name, String promoter, String startDate, String endDate) {

        String userId = getUserId();
        List<String> sqlList = new ArrayList<>();
        int total = 0;
        if (StringUtils.isNotEmpty(endDate)) {
            endDate = endDate.concat(" 23:59:59");
        }

        //系统待办
        total += getWorkItem(name, promoter, startDate, endDate, userId, sqlList);

        //课程预览申请
//        total += getCoursePreview(name,promoter,startDate,endDate,userId,sqlList);

        //评委评分
        total += getKcpf(name, promoter, startDate, endDate, userId, sqlList);

        //课程更新反馈
        total += getKcfk(name, promoter, startDate, endDate, userId, sqlList);

        List<Map<String, Object>> resultList = Collections.EMPTY_LIST;
        if (total > 0) {
            StringBuilder collect = new StringBuilder("select d.id,d.name,d.instanceId,d.date,d.type,d.schemaCode,u.name as creator from (")
                    .append(sqlList.stream().collect(Collectors.joining("\n UNION ALL \n")))
                    .append(") as d left join h_org_user u on d.creator = u.id  order by d.date desc ").append(getlimit(page, size));

            resultList = entityManager.createNativeQuery(collect.toString()).unwrap(NativeQueryImpl.class)
                    .setResultTransformer(Transformers.ALIAS_TO_ENTITY_MAP).getResultList();
        }

        Map<Object, Object> map = new HashMap<>();

        map.put("data", resultList);
        map.put("total", total);

        return getOkResponseResult(map, "成功");
    }

    //课程更新反馈
    private int getKcfk(String name, String promoter, String startDate, String endDate, String userId, List<String> sqlList) {
        StringBuilder kcgxfkSql = new StringBuilder("SELECT {} from  ").append(getTbName("kcgxfk")).append(" a where 1=1 ");


        //添加判断条件
        if (StringUtils.isNotEmpty(promoter)) {
            kcgxfkSql.append(" and a.creater  = '").append(promoter).append("'");
        }
        if (StringUtils.isNotEmpty(name)) {
            kcgxfkSql.append(" and a.gxhdmc like '%").append(name).append("%'");
        }
        if (StringUtils.isNotEmpty(startDate)) {
            kcgxfkSql.append(" and a.createdTime > '").append(startDate).append("'");
        }

        if (StringUtils.isNotEmpty(endDate)) {
            kcgxfkSql.append(" and a.createdTime < '").append(endDate).append("'");
        }
        kcgxfkSql.append(" and  a.kczkfr -> '$[0].id' ='").append(userId).append("'");

        kcgxfkSql.append(" and (!(a.fbzt ='已发布'  or a.gxfk = '不更新') or a.fbzt is NULL) ");

        // 课程更新活动状态标识_启用_取消
        kcgxfkSql.append("and cancel = '启用'");

        //课程更新反馈获取数据
        String kcgxfkData = "a.id,a.gxhdmc as name,'-' as instanceId,a.createdTime as date,4 as type,'kcgxfk' as schemaCode,a.creater as creator";
        BigInteger singleResult = (BigInteger) entityManager.createNativeQuery(StrUtil.format(kcgxfkSql, countSql)).getSingleResult();
        if (singleResult != null && singleResult.intValue() > 0) {
            sqlList.add(StrUtil.format(kcgxfkSql, kcgxfkData));
            return singleResult.intValue();
        }
        return 0;
    }

    //评委评分
    private int getKcpf(String name, String promoter, String startDate, String endDate, String userId, List<String> sqlList) {

        StringBuilder kcpfSql = new StringBuilder("SELECT {} from ").append(getTbName("kcpf"))
                .append(" a where a.zt ='未提交' and a.creater='").append(userId).append("'");

        //添加判断条件
        if (StringUtils.isNotEmpty(promoter)) {
            kcpfSql.append(" and a.kczkfr ->'$[0].id' = '").append(promoter).append("'");
        }
        if (StringUtils.isNotEmpty(name)) {
            kcpfSql.append(" and a.courseName like '%").append(name).append("%'");
        }
        if (StringUtils.isNotEmpty(startDate)) {
            kcpfSql.append(" and a.createdTime > '").append(startDate).append("'");
        }

        if (StringUtils.isNotEmpty(endDate)) {
            kcpfSql.append(" and a.createdTime < '").append(endDate).append("'");
        }


        //评委评分获取数据
        String kcpfData = "a.id,a.courseName as name,'-' as instanceId,a.createdTime as date,3 as type,'kcpf' as schemaCode,JSON_UNQUOTE(a.kczkfr ->'$[0].id') as creator";
        BigInteger singleResult = (BigInteger) entityManager.createNativeQuery(StrUtil.format(kcpfSql, countSql)).getSingleResult();
        if (singleResult != null && singleResult.intValue() > 0) {
            sqlList.add(StrUtil.format(kcpfSql, kcpfData));
            return singleResult.intValue();
        }
        return 0;
    }

    //课程预览申请
    private int getCoursePreview(String name, String promoter, String startDate, String endDate, String userId, List<String> sqlList) {

        StringBuilder coursePreviewSql = new StringBuilder("SELECT  {} from ").append(getTbName("coursePreview"))
                .append(" a where 1=1 ");

        //添加判断条件
        if (StringUtils.isNotEmpty(promoter)) {
            coursePreviewSql.append(" and a.creater = '").append(promoter).append("'");
        }
        if (StringUtils.isNotEmpty(name)) {
            coursePreviewSql.append(" and a.name like '%").append(name).append("%'");
        }
        if (StringUtils.isNotEmpty(startDate)) {
            coursePreviewSql.append(" and  a.createdTime > '").append(startDate).append("'");
        }

        if (StringUtils.isNotEmpty(endDate)) {
            coursePreviewSql.append(" and a.createdTime < '").append(endDate).append("'");
        }

        coursePreviewSql.append(" and (a.pfzt is null or a.pfzt ='') and  a.pfry ->'$[0].id' = '").append(userId).append("'");


        //课程预览申请获取数据
        String coursePreviewData = "a.id,a.name,'-' as instanceId,a.createdTime as date,2 as type,'coursePreview' as schemaCode,a.creater as creator";
        BigInteger singleResult = (BigInteger) entityManager.createNativeQuery(StrUtil.format(coursePreviewSql, countSql)).getSingleResult();
        if (singleResult != null && singleResult.intValue() > 0) {
            sqlList.add(StrUtil.format(coursePreviewSql, coursePreviewData));
            return singleResult.intValue();
        }

        return 0;
    }

    //系统待办
    private int getWorkItem(String name, String promoter, String startDate, String endDate, String userId, List<String> sqlList) {

        StringBuilder todoSql = new StringBuilder("SELECT {} from biz_workitem where participant ='").append(userId).append("'");
        //添加判断条件
        if (StringUtils.isNotEmpty(promoter)) {
            todoSql.append(" and originator = '").append(promoter).append("'");
        }
        if (StringUtils.isNotEmpty(name)) {
            todoSql.append(" and instanceName like '%").append(name).append("%'");
        }
        if (StringUtils.isNotEmpty(startDate)) {
            todoSql.append(" and startTime > '").append(startDate).append("'");
        }

        if (StringUtils.isNotEmpty(endDate)) {
            todoSql.append(" and startTime < '").append(endDate).append("'");
        }

        //系统待办获取数据
        String toDoData = "id,instanceName as name,instanceId,startTime as date,1 as type,'-' as schemaCode,originator as creator ";
        BigInteger singleResult = (BigInteger) entityManager.createNativeQuery(StrUtil.format(todoSql, countSql)).getSingleResult();
        if (singleResult != null && singleResult.intValue() > 0) {
            sqlList.add(StrUtil.format(todoSql, toDoData));
            return singleResult.intValue();
        }
        return 0;
    }


    private String getlimit(Integer page, Integer size) {

        if (page == null) {
            page = 1;
        }
        if (page < 1) {
            throw new RuntimeException("page 不能小于1");
        }

        if (size == null) {
            page = 10;
        }
        if (size < 1) {
            throw new RuntimeException("page 不能小于1");
        }
        page = (page - 1) * size;

        return StrUtil.format(" limit {},{}", page, size);
    }


    @GetMapping("getTodos")
    public ResponseResult getTodos(Integer page, Integer size){

        ResponseResult todoRest = this.getTodoList(page, size, null, null, null, null);

        if (todoRest.getErrcode() != 0) {
            return todoRest;
        }

        Map<String,Object> pages = (Map<String, Object>) todoRest.getData();
        Integer total = MapUtils.getInteger(pages, "total", 0);
        if (total == 0) {
            return null;
        }

        List<Map<String,Object>> list = (List<Map<String, Object>>) pages.get("data");

        String systemTodoTemp = "workflowInstanceId=%s&workitemId=%s";
        String todoTemp = "schemaCode=%s&objectId=%s";

        List<Map<String, Object>> mapList = list.stream().map(data -> {
            Integer type = MapUtils.getInteger(data,"type");
            String todoUrl;
            Map<String, Object> toMap = new HashMap<>();
            //系统待办
            if (type != null && type == 1) {
                todoUrl = String.format(systemTodoTemp, data.get("instanceId"), data.get("id"));
            } else {
                todoUrl = String.format(todoTemp, data.get("schemaCode"), data.get("id"));
            }
            toMap.put("workItemName", data.get("name"));
            toMap.put("workItemUrl", todoUrl);
            toMap.put("workItemReceiveTime", data.get("date"));
            return toMap;
        }).collect(Collectors.toList());

        pages.put("data", mapList);
        return todoRest;
    }

}
